package com.yesun.task.pipeline.quartz;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yesun.task.pipeline.common.CronUtil;
import com.yesun.task.pipeline.domain.po.JobLogPO;
import com.yesun.task.pipeline.handler.Executor;
import com.yesun.task.pipeline.handler.Loader;
import com.yesun.task.pipeline.service.JobLogService;
import com.yesun.task.pipeline.service.impl.JobLogServiceImpl;
import com.yesun.task.pipeline.worker.ParallelWorker;
import com.yesun.task.pipeline.domain.dto.JobDto;
import com.yesun.task.pipeline.handler.Handler;
import com.yesun.task.pipeline.handler.HandlerFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.yesun.task.pipeline.common.SpringUtil;
import org.quartz.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Calendar;

@Slf4j
public class QuartzJob implements Job {

    static SimpleDateFormat shortSdf = new SimpleDateFormat("yyyyMMdd");

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobKey jobKey = context.getJobDetail().getKey();
        log.info("触发JOB：" + jobKey.toString());
        //传递参数
        JobDataMap jobDataMap = context.getMergedJobDataMap();
        JobDto jobDto = (JobDto) jobDataMap.get("job");
        if(jobDto != null) {
            //判断依赖，如果有依赖，需要依赖JOB执行完毕 ，暂时只支持单个依赖
            if(StringUtils.isNotBlank(jobDto.getDependancyJobName())) {

                //持久化方式，TODO 暂时不支持，暂时支持从内存读取
//                //注意这里要取实现类，不能取接口
//                JobLogServiceImpl jobLogServiceImpl = (JobLogServiceImpl) SpringUtil.APPLICATION_CONTEXT.getBean("jobLogServiceImpl");
//                JobLogPO jobLogPO = jobLogServiceImpl.findByJobNameAndExecuteDate(jobDto.getDependancyJobName(), shortSdf.format(new Date()));
//                if(jobLogPO != null) {
//                    //表示已经执行过了
//                    log.info(jobLogPO.getJobName() + "已经在"+jobLogPO.getExecuteDate()+"执行完毕,执行状态" + jobLogPO.getStatus());
//                } else {
//                    log.info("依赖任务["+jobDto.getDependancyJobName() + "]任务尚未执行，请耐心等待!");
//                    //需要修改当前JOB的执行时间 TODO
//                    try {
//                        log.info("移除JOB：" +jobDto.getJobName());
//                        JobSchedule.removeJob(jobDto.getJobName());
//                        //添加新的JOB
//                        Calendar cal = Calendar.getInstance();
//                        cal.add(Calendar.MINUTE, 3);//未来三分钟
//                        String newCron = CronUtil.getCron(cal.getTime());
//                        log.info("new cron:" + newCron);
//                        Map<String, JobDto> map = new HashMap<>();
//                        map.put("job", jobDto);
//                        JobSchedule.addJob(jobDto.getJobName(), map, newCron, QuartzJob.class);
//                    } catch (SchedulerException e) {
//                        e.printStackTrace();
//                    }
//                    return;
//                }

                //注意这里要取实现类，不能取接口
                if(ParallelWorker.LIST_JOBS.contains(jobDto.getDependancyJobName())) {
                    //只有包含，才表示已经触发了JOB
                    // 然后判断TASK中是否存在，如果不存在，才表示执行完毕
                    if(ParallelWorker.MAP_TASK.containsValue(jobDto.getDependancyJobName())) {
                        //尚未执行完毕，需要等待
                        log.info("依赖任务["+jobDto.getDependancyJobName() + "]任务尚未执行，请耐心等待!");
                        //需要修改当前JOB的执行时间 TODO
                        try {
                            log.info("移除JOB：" +jobDto.getJobName());
                            JobSchedule.removeJob(jobDto.getJobName());
                            //添加新的JOB
                            Calendar cal = Calendar.getInstance();
                            cal.add(Calendar.MINUTE, 1);//等待1分钟
                            String newCron = CronUtil.getCron(cal.getTime());
                            log.info("new cron:" + newCron);
                            Map<String, JobDto> map = new HashMap<>();
                            map.put("job", jobDto);
                            JobSchedule.addJob(jobDto.getJobName(), map, newCron, QuartzJob.class);
                        } catch (SchedulerException e) {
                            e.printStackTrace();
                        }
                        return;
                    } else {
                        log.info("依赖JOB ["+jobDto.getDependancyJobName() + "]已经执行完毕！开始启动当前JOB["+jobDto.getJobName()+"]...");
                    }
                } else {
                    log.info("依赖任务["+jobDto.getDependancyJobName() + "]任务尚未执行，请耐心等待!");
                    //需要修改当前JOB的执行时间 TODO
                    try {
                        log.info("移除JOB：" +jobDto.getJobName());
                        JobSchedule.removeJob(jobDto.getJobName());
                        //添加新的JOB
                        Calendar cal = Calendar.getInstance();
                        cal.add(Calendar.MINUTE, 1);//等待1分钟
                        String newCron = CronUtil.getCron(cal.getTime());
                        log.info("new cron:" + newCron);
                        Map<String, JobDto> map = new HashMap<>();
                        map.put("job", jobDto);
                        JobSchedule.addJob(jobDto.getJobName(), map, newCron, QuartzJob.class);
                    } catch (SchedulerException e) {
                        e.printStackTrace();
                    }
                    return;
                }
            }
            //根据过来的参数构建采集任务，分发到handler
            Handler handler = HandlerFactory.getHandler(jobDto);
            ParallelWorker worker = new ParallelWorker(4);// 4个worker并行处理
            if(handler != null) {
                //注册executor，先注册
                Executor executor = handler.getExecutor();
                if(executor != null)
                    worker.registerExecutor(jobDto.getTag(), executor);
                //注册loader，后注册
                Loader loader = handler.getLoader();
                if(loader != null)
                    worker.registerLoader(jobDto.getTag(), loader);
            }
        } else {
            log.info("没有配置JOB信息！");
        }

    }
}
